﻿Option Strict On
Option Explicit On
Option Infer On

#Region "Imports"
Imports System
Imports System.Linq
Imports System.Xml.Linq
Imports System.Collections.Generic
Imports GenDotNet.TemplateData
Imports GenDotNet.TemplateSupport
Imports GenDotNet.TemplateSupport.Strings
#If CSharp Then
Imports GenDotNet.TemplateSupport.CSharp
#Else
Imports GenDotNet.TemplateSupport.VB
#End If
Imports GenDotNet.Task.Common
#End Region

Public Class EditableRootBaseTemplate
	Inherits DotNetLanguageBase

#Region "Required methods with static contents"
	Public Sub New()
		MyBase.New()
	End Sub

	' NEWTEMPLATE: Change to new guid for every new template
	Private ReadOnly _templateGuid As New Guid("{CC15462A-4362-403d-A3D1-6D5236920377}")
	Public Overrides ReadOnly Property Id() As System.Guid
		Get
			Return _templateGuid
		End Get
	End Property

	Protected Overrides Function GetFileImports() As TemplateSupport.ImportInfoCollection
		Return New CslaTemplate.Support.CslaImportInfoCollection
	End Function

	Protected Overrides Function GenerateFile() As String
		' NEWTEMPLATE: Exactly this code
		Return _
<code>
	<%= Me.OutputFile() %>
</code>.Value.CleanOutput
	End Function

	Protected Overrides Function GetFileName(ByVal element As System.Xml.Linq.XElement) As String
		' NEWTEMPLATE: Update the following file name
		Return OutputFilename(element.@Name)
	End Function
#End Region

	Protected Overrides Function GenerateContents() As String
		Dim classInfo = New TypeInfo(ObjectData.ClassName, Scope.Public, TypeCategory.Class, TypeModifiers.Partial)
		Return _
	  <code>

    ''------------------------------------------------------------------------------
    '' &lt;autogenerated>
    ''     This code was generated using CSLA 3.5 Template Collection.
    ''     Changes to this file may be lost if the code is regenerated.
    ''     Modify user class <%= ObjectData.ClassName %>.vb to extend this generated code. 
    ''
    ''     Code was generated at <%= Date.Now.ToString %> by <%= My.User.Name %>
    ''     Template path: <%= My.Application.Info.DirectoryPath %>
    ''     Template website: TBA
    '' &lt;/autogenerated>
    ''------------------------------------------------------------------------------

    &lt;Serializable> _
    Public Class <%= ObjectData.ClassName %>Base(Of T As RecipeBase(Of T))
        Inherits Csla.BusinessBase(Of T)
        <%= GenerateBusinessMethods() %>
		  <%= GenerateValidationRules() %>
		  <%= GenerateAuthorizationRules() %>
		  <%= GenerateValidationRules() %>
		  <%= GenerateFactoryMethods() %>

    End Class

End Namespace
</code>.Value
	End Function

	Private Function GenerateBusinessMethods() As String
		Return _
<code> 

    #Region " Business Properties and Methods "

        <%= GenerateProperties() %>

        Private Shared ChildrenProperty As PropertyInfo(Of ChildrenObject) = RegisterProperty(Of ChildrenObject)(GetType(<%= ObjectData.ClassName %>), New PropertyInfo(Of ChildrenObject)("Child FriendlyName"))
        Public ReadOnly Property Children() As ChildrenObject
            Get
                If Not FieldManager.FieldExists(ChildrenProperty) Then
                    SetProperty(Of ChildrenObject)(ChildrenProperty, ChildrenObject.NewChildrenObject())
                End If
                Return GetProperty(Of ChildrenObject)(ChildrenProperty)
            End Get
        End Property

        Public Overrides Function ToString() As String
            Return Id.ToString
        End Function
    
    #End Region ' Business Properties and Methods
</code>.Value
	End Function

	Private Function GenerateProperties() As String
		If ObjectData.Properties.Count > 0 Then

			Return _
			<code>
				<%= From x In ObjectData.Properties Select _
					<code>

  Private Shared <%= x.Name %>Property As PropertyInfo(Of <%= x.NetType %>) = RegisterProperty(Of <%= x.NetType %>)(GetType(<%= ObjectData.ClassName %>), New PropertyInfo(Of <%= x.NetType %>)("<%= x.Caption %>"))
  Public Property <%= x.Name %>() As <%= x.NetType %>
    Get
            Return GetProperty(Of <%= x.NetType %>)(<%= x.Name %>Property)
    End Get
    Set(ByVal value As <%= x.NetType %>)
            SetProperty(Of <%= x.NetType %>)(<%= x.Name %>Property, value)
    End Set
  End Property
      </code>.Value %>
			</code>.Value
		End If
		Return String.Empty
	End Function

	Private Function GenerateValidationRules() As String
		Return _
<code> 

    #Region " Validation Rules "

    ''' &lt;summary>
    ''' Method that allows the addition of custom business rules.
    ''' &lt;/summary>
    ''' &lt;remarks>This is purely a hook, all additions should be done in the User version of this class.&lt;/remarks>
    Protected Overridable Sub AddCustomRules()
    End Sub

    ''' &lt;summary>
    ''' Method that allows the addition of shared custom business rules.
    ''' &lt;/summary>
    ''' &lt;remarks;>This is purely a hook, all additions should be done in the User version of this class.&lt;/remarks>
    Protected Overridable Sub AddSharedCustomRules()
    End Sub

    ''' &lt;summary>
    ''' Method used to instigate the addition of all Business rules both Custom and Common.
    ''' &lt;/summary>
    Protected Overrides Sub AddInstanceBusinessRules()
        AddCustomRules()
        MyBase.AddInstanceBusinessRules()
    End Sub

    ''' &lt;summary>
    ''' Method that allows the addition of shared common business rules.
    ''' &lt;/summary>
    Protected Overridable Sub AddSharedCommonRules()
        ' Name rules
        ValidationRules.AddRule(AddressOf Csla.Validation.CommonRules.StringRequired, New Csla.Validation.RuleArgs(NameProperty))
        ValidationRules.AddRule(AddressOf Csla.Validation.CommonRules.StringMaxLength, New Validation.CommonRules.MaxLengthRuleArgs(NameProperty, 50))
    End Sub

    ''' &lt;summary>
    ''' Method used to instigate the addition of all Business rules both Custom and Common.
    ''' &lt;/summary>
    Protected Overrides Sub AddBusinessRules()
        AddSharedCommonRules()
        AddSharedCustomRules()
        MyBase.AddBusinessRules()
    End Sub

#End Region ' Validation Rules
</code>.Value
	End Function

	Private Function GenerateAuthorizationRules() As String
		Return _
<code> 

#Region " Authorization Rules "

  Protected Overrides Sub AddAuthorizationRules()
    ' add AuthorizationRules here
       <%= From x In ObjectData.Properties Select _
		   <code>
    AuthorizationRules.AllowWrite(<%= x.Name %>Property, "Administrator")
      </code>.Value %>
  End Sub

  Public Shared Function CanAddObject() As Boolean
    Return Csla.ApplicationContext.User.IsInRole("Administrator")
  End Function

  Public Shared Function CanGetObject() As Boolean
    Return True
  End Function

  Public Shared Function CanDeleteObject() As Boolean
    Dim result As Boolean
    If Csla.ApplicationContext.User.IsInRole("Administrator") Then
      result = True
    End If
    Return result
  End Function

  Public Shared Function CanEditObject() As Boolean
    Return Csla.ApplicationContext.User.IsInRole("Administrator")
  End Function

#End Region ' Authorization Rules
</code>.Value
	End Function

	Private Function GenerateFactoryMethods() As String
		Return _
<code> 
    
#Region " Factory Methods "

    Protected Sub New()
        ' require use of factory method in user object
    End Sub

#End Region ' Factory Methods
</code>.Value
	End Function

	Private Function GenerateDataAccess() As String
		Return _
<code> 
    
#Region " Data Access "

    <%= GenerateDataCreate() %>
	<%= GenerateDataFetch() %>
    
    
#End Region ' Data Access
</code>.Value
	End Function

	Private Function GenerateDataCreate() As String
		Return _
<code> 

#Region " Data Access "

  &lt;RunLocal()> _
  Protected Overrides Sub DataPortal_Create()
    SetDefaults()
    ValidationRules.CheckRules()
  End Sub

    Protected Overridable Sub SetDefaults()
    End Sub
#End Region ' Data Access
</code>.Value
	End Function

	Private Function GenerateDataFetch() As String
		Return _
<code> 

#Region " Data Access "

  Private Overloads Sub DataPortal_Fetch(ByVal criteria As SingleCriteria(Of Project, Guid))
    Using ctx = ContextManager(Of ProjectTracker.DalLinq.PTrackerDataContext).GetManager(Database.PTrackerConnection)
      ' get project data
      Dim data = (From p In ctx.DataContext.Projects Where p.Id = criteria.Value Select p).Single
      LoadProperty(Of Guid)(IdProperty, data.Id)
      LoadProperty(Of String)(NameProperty, data.Name)
      LoadProperty(Of SmartDate, Date?)(StartedProperty, data.Started)
      LoadProperty(Of SmartDate, Date?)(EndedProperty, data.Ended)
      LoadProperty(Of String)(DescriptionProperty, data.Description)
      mTimestamp = data.LastChanged.ToArray

      ' get child data
      LoadProperty(Of ProjectResources)(ResourcesProperty, _
        ProjectResources.GetProjectResources(data.Assignments.ToArray))
    End Using
  End Sub

#End Region ' Data Access
</code>.Value
	End Function

	Private Function GenerateDataInsert() As String
		Return _
<code> 

#Region " Data Access "

  Protected Overrides Sub DataPortal_Insert()
    Using ctx = ContextManager(Of ProjectTracker.DalLinq.PTrackerDataContext).GetManager(Database.PTrackerConnection)
      ' insert project data
      Dim lastChanged As System.Data.Linq.Binary = Nothing
      ctx.DataContext.addProject(GetProperty(Of Guid)(IdProperty), _
                                 GetProperty(Of String)(NameProperty), _
                                 GetProperty(Of SmartDate)(StartedProperty), _
                                 GetProperty(Of SmartDate)(EndedProperty), _
                                 GetProperty(Of String)(DescriptionProperty), _
                                 lastChanged)
      mTimestamp = lastChanged.ToArray
      ' update child objects
      DataPortal.UpdateChild(GetProperty(Of ProjectResources)(ResourcesProperty), Me)
    End Using
  End Sub

#End Region ' Data Access
</code>.Value
	End Function

	Private Function GenerateDataUpdate() As String
		Return _
<code> 

#Region " Data Access "

  Protected Overrides Sub DataPortal_Update()
    Using ctx = ContextManager(Of ProjectTracker.DalLinq.PTrackerDataContext).GetManager(Database.PTrackerConnection)
      ' insert project data
      Dim lastChanged As System.Data.Linq.Binary = Nothing
      ctx.DataContext.UpdateProject(GetProperty(Of Guid)(IdProperty), _
                                    GetProperty(Of String)(NameProperty), _
                                    GetProperty(Of SmartDate)(StartedProperty), _
                                    GetProperty(Of SmartDate)(EndedProperty), _
                                    GetProperty(Of String)(DescriptionProperty), _
                                    mTimestamp, _
                                    lastChanged)
      mTimestamp = lastChanged.ToArray
      ' update child objects
      DataPortal.UpdateChild(GetProperty(Of ProjectResources)(ResourcesProperty), Me)
    End Using
  End Sub

#End Region ' Data Access
</code>.Value
	End Function

	Private Function GenerateDataDelete() As String
		Return _
<code> 

#Region " Data Access "

  Protected Overrides Sub DataPortal_DeleteSelf()
    DataPortal_Delete(New SingleCriteria(Of Project, Guid)(GetProperty(Of Guid)(IdProperty)))
  End Sub

  &lt;Transactional(TransactionalTypes.TransactionScope)> _
  Private Overloads Sub DataPortal_Delete(ByVal criteria As SingleCriteria(Of Project, Guid))
    Using ctx = ContextManager(Of ProjectTracker.DalLinq.PTrackerDataContext).GetManager(Database.PTrackerConnection)
      ' delete project data
      Dim lastChanged As System.Data.Linq.Binary = Nothing
      ctx.DataContext.DeleteProject(criteria.Value)
      ' reset child list field
      SetProperty(Of ProjectResources)(ResourcesProperty, ProjectResources.NewProjectResources)
    End Using
  End Sub

#End Region ' Data Access
</code>.Value
	End Function

End Class
